from django.shortcuts import render
from django.http import HttpResponse, HttpResponseBadRequest
import requests, datetime, json
import apiv2.models as models
import logging
import dynamicloselist.views as dynamiclostlist

apiweixin = 'https://api.weixin.qq.com/sns/jscode2session?' \
            'appid=wx5b9b3b137abe9aa2&secret=04c81f05f3f7a722e08bcfda22460abd&' \
            'js_code={}&grant_type=authorization_code'
loselist = [100, 50, 33, 13, 9, 6, 4, 3]

# 日志类
logger = logging.getLogger(__name__)
collect_logger = logging.getLogger('collect')


# *工具类1：返回json字符串
def resUTF8(res):
    return HttpResponse(
        res,
        content_type='application/json',
        charset='utf-8'
    )
# Create your views here.

# ***0. 程序入口
def index(request, kind):
    data = request.GET
    mothodname_suffix = '_' + data.get('op')
    methodname = kind + mothodname_suffix
    try:
        result = eval(methodname)(data)
    except Exception as e:
        logger.debug(e)
        logger.error(e)
        return HttpResponseBadRequest()
    logger.debug('eval({}({})) return{}'.format(methodname, data, result))
    return resUTF8(result)


# *1. 获取openid
def User_getOpenId(data):
    js_code = data.get('js_code')
    res = requests.get(url=apiweixin.format(js_code))
    res_text = ''
    while True:
        res_text = res.json().get('openid')
        if res_text is not None:
            logger.debug('re_text.openid为{}'.format(res_text))
            break
        else:
            logger.debug('re_text.openid为{}，重新发送请求'.format(res_text))
    result = json.dumps(res_text, ensure_ascii=False)
    return result


# *2. 添加或更新user信息
def User_addOrUpdate(data):
    openId = data.get('openId')
    name = data.get('name')
    pic = data.get('pic')
    user, donhave = models.User.objects.get_or_create(openid=openId)
    user.openid = openId
    user.name = name
    user.pic = pic
    user.save()
    if not donhave:
        logger.debug('更新用户{}'.format(user.name))
    else:
        logger.debug('添加用户{}'.format(user.name))
        dynamiclostlist.create_lose_rate(
            {
                'userId': user.id
            }
        )
    result = json.dumps(user.id, ensure_ascii=False)
    return result


# *3. 获取 plan 里 分数小于100的card列表
def Plan_getCards(data):
    userId = data.get('userId')
    plans = models.Plan.objects.filter(
        user_id=userId,
    )
    # 更新plan(lastUpdate,point)
    now_time = datetime.datetime.now().date()
    # 遍历 plans
    for plan in plans:
        lastUpdate = plan.lastUpdate  # 上次更新时间
        plan.lastUpdate = now_time  # 更新lastUpdate
        de_time = (now_time - lastUpdate).days  # 相隔天数
        plancount = plan.count
        planpoint = plan.point
        # 更新point
        # 判断有没有学习 或者 今天已经 更新过
        if plancount != 0 and de_time != 0:  # 如果学习过且 未更新 则更新point
            # 计算需要减少的分数
            dy_loselist = dynamiclostlist.get_lose_rate(
                {
                    'userId':userId
                }
            )
            if dy_loselist != []:
                loselist = dy_loselist
            if plancount < 8:
                de_point = de_time * loselist[plancount - 1]
            else:
                de_point = de_time * loselist[plancount - 1]  # 计算需要减少的分数
            if de_point > planpoint + 100:  # 如果de_point 过大，
                plan.point = -100           # 则将point置为最小值-100
            else:  # 否则，point为原point减去de_point
                plan.point = planpoint - de_point
        plan.save()  # 保存修改
    # 获取分数小于100的card列表
    plans = models.Plan.objects.filter(
        user_id=userId,
        point__lt=100,
    ).order_by('point')
    cardslist = []
    for plan in plans:
        card = plan.card
        cardslist.append(
            {
                'id': card.id,
                'bookId': plan.book_id,
                'title': card.title,
                'content': card.content,
                'level': card.level,
                'type': card.type,
                'point': plan.point,
            }
        )
    # result = json.dumps({
    #     'success': 1,
    #     'Cards': cardslist
    # }, ensure_ascii=False)
    result = json.dumps(cardslist,ensure_ascii=False)
    return result


# *4. 更新plan(lastLearn,count,point)
def Plan_addOrUpdate(data):
    cardId = data.get('cardId')
    userId = data.get('userId')
    bookId = data.get('bookId')
    flag = data.get('flag')
    now_time = datetime.datetime.now().date()
    planfilter = models.Plan.objects.filter(
            card_id=cardId,
            user_id=userId,
            book_id=bookId,
    )
    if planfilter.count() > 0:
        plan = planfilter[0]
        logger.debug('更新Plan')
        lastLearn = plan.lastLearn
        # 更新count , lastLearn
        # 如果 最后学习的时间 不是今天 ，则更新 学习时间 并是count + 1
        # 且 添加 学习记录
        if now_time != lastLearn:
            dynamiclostlist.add_learn_log(
                {
                    'userId': userId,
                    'cardId': cardId,
                    'learnCount': plan.count + 1,
                    'logInfo': flag,
                }
            )
            plan.lastLearn = now_time
            plan.count = plan.count + 1
    else:
        # 新 计划
        logger.debug('添加Plan')
        plan = models.Plan(
            card_id=cardId,
            user_id=userId,
            book_id=bookId,
            lastUpdate=now_time,
            lastLearn=now_time,
            count=1,
            point=0,
        )
        dynamiclostlist.add_learn_log(
            {
                'userId': userId,
                'cardId': cardId,
                'learnCount': 1,
                'logInfo': flag,
            }
        )
        # 更新 book中的res(剩余卡片减 1)
        try:
            userbook = models.User_Books.objects.get(
                user=userId,
                book=bookId,
            )
            userbook.res = userbook.res - 1
            userbook.save()
        except Exception as e:
            logger.error(e)
            result = json.dumps(0,ensure_ascii=False)
            return result
    # try:
    #     # 旧 计划
    #     plan = models.Plan.objects.get(
    #         card_id=cardId,
    #         user_id=userId,
    #         book_id=bookId,
    #     )
    #     logger.debug('更新Plan')
    #     lastLearn = plan.lastLearn
    #     # 更新count , lastLearn
    #     # 如果 最后学习的时间 不是今天 ，则更新 学习时间 并是count + 1
    #     # 且 添加 学习记录
    #     if now_time != lastLearn:
    #         dynamiclostlist.add_learn_log(
    #             {
    #                 'userId':userId,
    #                 'cardId':cardId,
    #                 'learnCount':plan.count + 1,
    #                 'logInfo':flag,
    #             }
    #         )
    #         plan.lastLearn = now_time
    #         plan.count = plan.count + 1
    # except Exception as e:
    #     # 新 计划
    #     logger.debug(str(e) + '添加Plan')
    #     plan = models.Plan(
    #         card_id=cardId,
    #         user_id=userId,
    #         book_id=bookId,
    #         lastUpdate=now_time,
    #         lastLearn=now_time,
    #         count=1,
    #         point=0,
    #     )
    #     dynamiclostlist.add_learn_log(
    #         {
    #             'userId': userId,
    #             'cardId': cardId,
    #             'learnCount': 1,
    #             'logInfo': flag,
    #         }
    #     )
    #     # 更新 book中的res(剩余卡片减 1)
    #     try:
    #         userbook = models.User_Books.objects.get(
    #             user=userId,
    #             book=bookId,
    #         )
    #         userbook.res = userbook.res - 1
    #         userbook.save()
    #     except Exception as e:
    #         logger.error(e)
    #         result = json.dumps(0,ensure_ascii=False)
    #         return result

    # 更新 point
    if flag == 'know':
        plan.point = 300
    elif flag == 'blur':
        plan.point = 100
    elif flag == 'unknow':
        plan.point = 0
    else:
        plan.point = 0
    # 保存 plan
    try:
        plan.save()
    except Exception as e:
        # result = json.dumps({
        #     'success': 0,
        #     'msg': '保存失败，请重试！'
        # }, ensure_ascii=False)
        result = 0
        logger.error(e)
    else:
        # result = json.dumps({
        #     'success': 1,
        # }, ensure_ascii=False)
        result = 1
        logger.debug('Plan保存成功')
    return result


# *5. 获取 评论数量
def Comment_getCnt(data):
    try:
        cardId = data.get('cardId')
        count = models.Comment.objects.filter(card_id=cardId).count()
        # result = json.dumps({
        #     'success': 1,
        #     'Cnt': count
        # }, ensure_ascii=False)
        result = json.dumps(count, ensure_ascii=False)
    except Exception as e:
        logger.error(e)
        result = json.dumps(0, ensure_ascii=False)
    return result


# *6. 获取 评论列表
def Comment_getComments(data):
    cardId = data.get('cardId')
    try:
        comments = models.Comment.objects.filter(card_id=cardId)
        if comments.count() == 0:
            commentlist = []
            logger.debug('这个card没有评论')
        else:
            commentlist = []
            for comment in comments:
                commentlist.append(
                    {
                        'card': comment.card_id,
                        'name': comment.user.name,
                        'pic': comment.user.pic,
                        'content': comment.content,
                        'likes': comment.likes,
                    }
                )
    except Exception as e:
        commentlist = []
        logger.error(e)

    result = json.dumps(commentlist, ensure_ascii=False)
    return result


# *7.获取 用户收藏的书籍列表
def Book_getBooks(data):
    userId = data.get('userId')
    # 获取用户对象
    try:
        user = models.User.objects.get(id=userId)
        # 获取用户对象的 书籍列表
        books = user.books.filter()
        booklist = []
        for book in books:
            booklist.append(
                {
                    'id': book.id,
                    'title': book.title,
                    'msg': book.msg,
                    'type': book.type,
                    'pic': book.pic,
                    'res': models.User_Books.objects.get(user=user, book=book).res
                }
            )
    except Exception as e:
        booklist = []
        logger.error(e)

    result = json.dumps(booklist, ensure_ascii=False)
    return result


# *8. Book :获取 book 里的card
def Book_getCards(data):
    bookId = data.get('bookId')
    try:
        book = models.Book.objects.get(id=bookId)
        cards = book.cards.filter()
        cardlist = []
        for card in cards:
            cardlist.append(
                {
                    'id': card.id,
                    'title': card.title,
                    'content': card.content,
                    'level': card.level,
                    'type': card.type,
                }
            )
        if len(cardlist) == 0:
            logger.debug('这本书里没有卡片')
    except Exception as e:
        cardlist = []
        logger.error(e)
    result = json.dumps(cardlist, ensure_ascii=False)
    return result


# **9. Comment:添加 Comment
def Comment_addComment(data):
    userId = data.get('userId')
    cardId = data.get('cardId')
    content = data.get('content')

    try:
        models.Comment(
            user_id=userId,
            card_id=cardId,
            content=content,
            likes=0,
        ).save()
        result = json.dumps(1, ensure_ascii=False)
    except Exception as e:
        logger.error(e)
        result = json.dumps(0, ensure_ascii=False)
    return result



# 19-5-12
# *10. 移除用户的书籍
def Book_removeMyBook(data):
    userId = data.get('userId')
    bookId = data.get('bookId')
    try:
        book = models.User_Books.objects.filter(
            user_id=userId,
            book_id=bookId,
        )
        if book.count() != 0:
            book.delete()
        else:
            logger.debug('用户没有这本书')
        result = json.dumps(1, ensure_ascii=False)
    except Exception as e:
        logger.error(e)
        result = json.dumps(0, ensure_ascii=False)
    return result


# *11. 获取全部 书籍
def Book_getAllBooks(data):
    try:
        books = models.Book.objects.all()
        booklist = []
        for book in books:
            booklist.append(
                {
                    'id': book.id,
                    'title': book.title,
                    'msg': book.msg,
                    'type': book.type,
                    'pic': book.pic,
                }
            )
    except Exception as e:
        logger.error(e)
        booklist = []
    result = json.dumps(booklist, ensure_ascii=False)
    return result


# *12. 添加 book到用户
def Book_addMyBook(data):
    userId = data.get('userId')
    bookId = data.get('bookId')
    try:
        book = models.Book.objects.get(id=bookId)
        user = models.User.objects.get(id=userId)
        res = book.cards.count() - models.Plan.objects.filter(
            book=book,
            user=user,
        ).count()
        if not user.user_books_set.filter(book=book).exists():
            models.User_Books(
                user=user,
                book=book,
                res=res,
            ).save()
        else:
            logger.debug('书籍 {}已被用户收藏'.format(bookId))
        result = json.dumps(1, ensure_ascii=False)
    except Exception as e:
        logger.error(e)
        result = json.dumps(0, ensure_ascii=False)
    return result


# *13. 获取 学习列表需要学习（复习）的列表的长度
def Plan_getCardsCnt(data):
    userId = data.get('userId')
    try:
        plans = models.Plan.objects.filter(
            user_id=userId,
        )
        # 更新plan(lastUpdate,point)
        now_time = datetime.datetime.now().date()
        # 遍历 plans
        for plan in plans:
            lastUpdate = plan.lastUpdate  # 上次更新时间
            plan.lastUpdate = now_time  # 更新lastUpdate
            de_time = (now_time - lastUpdate).days  # 相隔天数
            plancount = plan.count
            planpoint = plan.point
            # 更新point
            # 判断有没有学习 或者 今天已经 更新过
            if plancount != 0 and de_time != 0:  # 如果学习过且 未更新 则更新point
                # 计算需要减少的分数
                dy_loselist = dynamiclostlist.get_lose_rate(
                    {
                        'userId': userId
                    }
                )
                if dy_loselist != []:
                    loselist = dy_loselist
                if plancount < 8:
                    de_point = de_time * loselist[plancount - 1]
                else:
                    de_point = de_time * loselist[plancount - 1]  # 计算需要减少的分数
                if de_point > planpoint + 100:  # 如果de_point 过大，则将point置为最小值-100
                    plan.point = -100
                else:  # 否则，point为原point减去de_point
                    plan.point = planpoint - de_point
            plan.save()  # 保存修改
        # 获取分数小于100的card列表大小
        cardCnt = models.Plan.objects.filter(
            user_id=userId,
            point__lt=100,
        ).count()
    except Exception as e:
        cardCnt = 0
        logger.error(e)
    result = json.dumps(cardCnt, ensure_ascii=False)
    return result


# *14. 获取 学习列表总长度
def Plan_getLearnedCnt(data):
    userId = data.get('userId')
    try:
        plans = models.Plan.objects.filter(
            user_id=userId,
        )
        learnedCnt = plans.count()
    except Exception as e:
        logger.error(e)
        learnedCnt = 0
    result = json.dumps(learnedCnt, ensure_ascii=False)
    return result


# *15. 返回用户收藏的card列表
def Card_getMyCards(data):
    userId = data.get('userId')
    try:
        user = models.User.objects.get(id=userId)
        mycards = user.favorite.filter()
        mycardlist = []
        for mycard in mycards:
            mycardlist.append(
                {
                    'id': mycard.id,
                    'title': mycard.title,
                    'content': mycard.content,
                    'level': mycard.level,
                    'type': mycard.type,
                }
            )
    except Exception as e:
        mycardlist = []
        logger.error(e)
    result = json.dumps(mycardlist, ensure_ascii=False)
    return result


# *16. 返回单个card
def Card_getCard(data):
    cardId = data.get('cardId')
    try:
        card = models.Card.objects.get(id=cardId)
        result = json.dumps(
            {
                'id': card.id,
                'title': card.title,
                'content': card.content,
                'level': card.level,
                'type': card.type,
            }, ensure_ascii=False
        )
    except Exception as e:
        result = json.dumps({}, ensure_ascii=False)
        logger.error(e)
    return result

# 17. 返回收藏卡片 ID 列表
def Card_getMyCardIds(data):
    userId = data.get('userId')
    try:
        user = models.User.objects.get(id=userId)
        mycards = user.favorite.filter()
        mycardlist = []
        for mycard in mycards:
            mycardlist.append(
                 mycard.id
            )
    except Exception as e:
        mycardlist = []
        logger.error(e)
    result = json.dumps(mycardlist, ensure_ascii=False)
    return result

# *18. 添加用户card收藏
def Card_addLike(data):
    userId = data.get('userId')
    cardId = data.get('cardId')
    try:
        user = models.User.objects.get(id=userId)
        card = models.Card.objects.get(id=cardId)
        user.favorite.add(card)
        result = json.dumps(1, ensure_ascii=False)
    except Exception as e:
        result = json.dumps(0, ensure_ascii=False)
        logger.error(e)
    return result


# *19. 删除用户card收藏
def Card_removeLike(data):
    userId = data.get('userId')
    cardId = data.get('cardId')
    try:
        user = models.User.objects.get(id=userId)
        card = models.Card.objects.get(id=cardId)
        user.favorite.remove(card)
        result = json.dumps(1, ensure_ascii=False)
    except Exception as e:
        result = json.dumps(0, ensure_ascii=False)
        logger.error(e)
    return result


# *20. 返回已经 Plan中的card 列表
def Plan_getLearnedCards(data):
    userId = data.get('userId')
    userId = data.get('userId')
    try:
        plans = models.Plan.objects.filter(
            user_id=userId,
        )
        cardslist = []
        for plan in plans:
            card = plan.card
            cardslist.append(
                {
                    'id': card.id,
                    'bookId': plan.book_id,
                    'title': card.title,
                    'content': card.content,
                    'level': card.level,
                    'type': card.type,
                    'point': plan.point,
                }
            )
        result = json.dumps(cardslist, ensure_ascii=False)
    except Exception as e:
        logger.error(e)
        result = json.dumps([], ensure_ascii=False)
    return result

#  *?.Plan :用户 添加 Book 到收藏中
# def Book_addBook(data):
#     userId = data.get('userId')
#     bookId = data.get('bookId')
#     # 更新用户书籍收藏表
#     user = models.User.objects.get(
#         userid=userId,
#     )
#     a, is_created = user.books.get_or_create(book=bookId)
#     if not is_created:  # 用户书籍收藏已经存在
#         # result = json.dumps({
#         #     'success': 0,
#         #     'msg': '书籍已在用户收藏列表中'
#         # }, ensure_ascii=False)
#         result = json.dumps(0, ensure_ascii=False)
#         return result
#     else:
#         # result = json.dumps({
#         #     'success': 0,
#         # }, ensure_ascii=False)
#         result = json.dumps(0, ensure_ascii=False)
#         return result
    # # 2. 更新用户学习计划
    # # 根据bookid 获取 book 的 card id 集合
    # book = models.Book.objects.get(
    #     id=bookId
    # )
    # cards = book.cards.filter()
    # now_time = datetime.datetime.now().date()
    # for card in cards:
    #     models.Plan(
    #         card=card,
    #         book=book,
    #         user_id=userId,
    #         lastUpdate=now_time,
    #         lastLearn=now_time,
    #         count=0,
    #         point=0,
    #     ).save()
    # result = json.dumps({
    #     'success': 1,
    # }, ensure_ascii=False)
    # return result
